package GUI;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.util.Collection;
import java.util.Map;

import org.apache.commons.collections15.Factory;

import Config.Configure;
import Statistics.CompositeGraph;
import Statistics.IDGraph;
import Statistics.IDGraphGlobalProperty;
import Statistics.IDGraphNode;
import Statistics.IDGraphToJungGraph;
import Statistics.TarjanSCC;
import Statistics.IDGraphToJungGraph.MyEdge;
import Statistics.IDGraphToJungGraph.MyNode;
import Store.StoreManager;
import edu.uci.ics.jung.graph.DirectedSparseGraph;
import edu.uci.ics.jung.graph.Graph;
import edu.uci.ics.jung.graph.SparseMultigraph;
import edu.uci.ics.jung.io.PajekNetReader;

public class DataFrontier {
	private String seed;
	private IDGraphGlobalProperty globalProperty;
	@Deprecated
	private IDGraph               idGraph;
	private DirectedSparseGraph<String, IDGraphToJungGraph.MyEdge> jungGraph;
	
	private void LoadData()
	{
		//load globalProperty...
		FileInputStream fis = null;
		ObjectInputStream ois = null;
		try {
			fis = new FileInputStream(Configure.GLOBAL_PROPERTY_FILE_PATH);
			 ois = new ObjectInputStream(fis);
			globalProperty = (IDGraphGlobalProperty)ois.readObject();

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e)
		{
		    e.printStackTrace();
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
				fis.close();
				ois.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
		//get id graph from database...
		StoreManager smr = new StoreManager();
		smr.SetUpGraphDatabase(Configure.GRAPH_DB_DIR);
		idGraph = new IDGraph();
		idGraph.SetNodeMap(smr.GetIDGraphData());
		smr.Close();
		//construct jungGraph 
		jungGraph = IDGraphToJungGraph.ToSparseGraph(idGraph);
		
		//load jungGraph from pajek format file...
		/*
		Factory<MyEdge> ef = new Factory<MyEdge>() {
			public MyEdge create()
			{
				return new MyEdge(0, 0);
			}
		};
		PajekNetReader<Graph<String,IDGraphToJungGraph.MyEdge>,String, IDGraphToJungGraph.MyEdge> pnr
						= new PajekNetReader<Graph<String,IDGraphToJungGraph.MyEdge>, String, IDGraphToJungGraph.MyEdge>(ef);
		try {
			FileInputStream fis2 = new FileInputStream(Configure.PAJEK_DIR);
			InputStreamReader isr = new InputStreamReader(fis2);
			BufferedReader br = new BufferedReader(isr);
			jungGraph = new DirectedSparseGraph<String,MyEdge>();
			pnr.load(br,jungGraph);
			fis2.close();
			isr.close();
			br.close();
		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		*/
	}
	
	public DataFrontier()
	{
		LoadData();
	}
	
	/**
	 * This function is just for test...
	 */
	public void showGraph()
	{
		System.out.println("Vertices count: "+jungGraph.getVertexCount());
		System.out.println("Edges count:"+jungGraph.getEdgeCount());
		Collection<MyEdge> edges = jungGraph.getEdges();
		for (MyEdge edge : edges) {
			System.out.println(edge);
		}
		
		Collection<String> vertice = jungGraph.getVertices();
		for (String vertex:vertice) {
			System.out.println(vertex);
		}
	}
	
	public DirectedSparseGraph<String, MyEdge> GetJungFormatGraph()
	{
		return jungGraph;
	}
	
	public IDGraph GetIDGraph()
	{
		return idGraph;
	}
	
	public IDGraphGlobalProperty GetGlobalProperty()
	{
		return globalProperty;
	}
	
	public IDGraph GenerateRandomSubGraph(int nodecount,int degree)
	{
		/*
		int max = idGraph.GetNodeMap().size();
		int index;
		do{
			index = ((int)Math.random()*max+1);
		}while(index<1||index>=max);
		*/
		seed = null;
		for(IDGraphNode node:idGraph.GetNodeMap().values())
		{
			if(node.GetOutDegree()>degree)
			{
				seed = node.GetID();
				break;
			}
		}
		return TarjanSCC.GetSubGraph(idGraph, seed, nodecount);
	}
	
	public String GetSeed()
	{
		return seed;
	}
	/**
	 * This function is just for test...
	 */
	protected CompositeGraph GenerateCompositeGraphForTest(int nodecount,int edgecount)
	{
		CompositeGraph graph = new CompositeGraph();
		for(int i=0;i<nodecount;i++)
		{
			graph.AddNode("SCC"+i, i);
		}
		for(int i=0;i<edgecount;i++)
		{
			int source = (int) (Math.random()*nodecount);
			int sink = (int)(Math.random()*nodecount);
			int weight = (int)(1000*Math.random()); 
			graph.AddEdge("SCC"+source,"SCC"+sink,weight);
		}
		return graph;
	}
	
	public DirectedSparseGraph<MyNode, MyEdge> GenerateRandomSCCView(int nodecount,int edgecount)
	{
	   return IDGraphToJungGraph.NewCompositeGraphToSparseGraph(GenerateCompositeGraphForTest(nodecount, edgecount));
	}
	
	
	public static IDGraph GenerateIDGraphForTest()
	{
		IDGraph res = new IDGraph();
		res.AddNode("Node1");
		res.AddNode("Node2");
		res.AddNode("Node3");
		res.AddNode("Node4");
		res.AddNode("Node5");
		res.AddNode("Node6");
		
		res.AddEdge("Node1", "Node2");
		res.AddEdge("Node2", "Node3");
		res.AddEdge("Node3", "Node1");
		res.AddEdge("Node4", "Node5");
		res.AddEdge("Node5", "Node6");
		res.AddEdge("Node6", "Node4");
		
		res.AddEdge("Node1", "Node4");
		return res;
	}
}
